/*
   Copyright 2007 Carsten Saager (carsten@saager.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package org.saager.traits.junit;

import java.text.NumberFormat;

import javax.swing.text.NumberFormatter;

import junit.framework.TestCase;

import org.saager.traits.Traits;
import org.saager.traits.test.Agent;
import org.saager.traits.test.Client;
import org.saager.traits.test.Formatter;
import org.saager.traits.test.IAgent;
import org.saager.traits.test.IClient;
import org.saager.traits.test.IFormatter;
import org.saager.traits.test.IPrint;
import org.saager.traits.test.Print;


public class TraitTest extends TestCase {
	public void testTraitedVanilla() throws Exception {
		// make empty Trait
		Traits traited = new Traits();
		
		// we create an Object
		IClient c = (IClient) traited.with(new Client("Carsten", "Saager")).traited();
		
		// and it is usable!
		assertEquals("Carsten", c.getGivenname());
		
		// add the getFullName to our traited object
		IPrint p = (IPrint) traited.with(Print.FACTORY).traited();

		// looks correct
		assertEquals("SAAGER, Carsten", p.getFullName());
		
		//now some more complicated
		final NumberFormatter cf = new NumberFormatter(NumberFormat.getCurrencyInstance());

		// adding the number format
		traited.with(new Formatter(NumberFormat.getCurrencyInstance()));
		
		// a special client sub type
		new Agent(traited); // adds itself to the traits
		IAgent ai = (IAgent) traited.traited();
		
		// set a value
		ai.setCommission(2.21);
		
		// we can get it back
		assertEquals(2.21, ai.getCommission());
		
		// and Agent now uses our formatter!
		assertEquals(cf.valueToString(2.21), ai.commisionToString());
		// as well here
		assertEquals(p.getFullName()+" "+cf.valueToString(2.21)
				,ai.toString());

		// add a better format:
		IFormatter formatter = new Formatter(NumberFormat.getPercentInstance());
		traited.with(formatter);
		
		// the new formatter is used as it is called on virtual()
		assertEquals(p.getFullName()+" "+formatter.format(2.21), ai.toString());

		// still the same as commissionToString uses overridden()
		assertEquals(cf.valueToString(2.21), ai.commisionToString());
		
		// get rid of the new formatter
		traited.remove(formatter);
		
		// and everything is like before
		assertEquals(p.getFullName()+" "+cf.valueToString(2.21), ai.toString());
		
	}
	
	public interface A {
		void a();
	}
	

	int at;
	@SuppressWarnings("deprecation")
	public void testOverride() {
		Traits t = new Traits();
		Traits withAA = t.with(new A(){

			public void a() {
				at=1;
			}
			
		});
		Traits withA = withAA.with(new A(){
			public void a() {
				at=2;
			}

		}, new Class[]{}); //should ignore implementation
		
		// demonstrated defect 1
		((A)withAA.traited()).a();
		assertEquals(1, at); // after correction

	}
}
